package main;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.TextBox;
import javax.obex.HeaderSet;

import control.ControlCommand;
import control.GroupControl;
import control.HueSlider;
import control.SaturationSlider;
import control.TextButton;
import control.ValueSlider;

public class ColorCanvas extends Canvas {
	Displayable previousCanvas;
	ColorHandler colorHandler;
	MainMidlet midlet;
	GroupControl colorBox;
	HueSlider hueSlider;
	SaturationSlider saturationSlider;
	ValueSlider valueSlider;
	int originalColor = 0;
	int newColor = 0;

	public ColorCanvas(MainMidlet mainMidlet) {
		// TODO Auto-generated constructor stub
		setFullScreenMode(true);
		midlet = mainMidlet;
		hueSlider = new HueSlider(10, 30, 35, 340);
		hueSlider.setCommand(new ControlCommand() {
			public void Do() {
				// TODO Auto-generated method stub
				saturationSlider.setHue(hueSlider.getHue());
				valueSlider.setHue(hueSlider.getHue());
				newColor = HSV2RGB(hueSlider.getHue(),
						saturationSlider.getSaturation(),
						valueSlider.getColorValue());
			}
		});

		saturationSlider = new SaturationSlider(60, 30, 35, 340);
		saturationSlider.setCommand(new ControlCommand() {
			public void Do() {
				// TODO Auto-generated method stub

				valueSlider.setSaturation(saturationSlider.getSaturation());
				newColor = HSV2RGB(hueSlider.getHue(),
						saturationSlider.getSaturation(),
						valueSlider.getColorValue());
			}
		});

		valueSlider = new ValueSlider(110, 30, 35, 340);
		valueSlider.setCommand(new ControlCommand() {
			public void Do() {
				// TODO Auto-generated method stub
				newColor = HSV2RGB(hueSlider.getHue(),
						saturationSlider.getSaturation(),
						valueSlider.getColorValue());
			}
		});
		colorBox = new GroupControl(4);
		colorBox.setControl(0, hueSlider);
		colorBox.setControl(1, saturationSlider);
		colorBox.setControl(2, valueSlider);

		colorBox.setControl(3, new TextButton("Ok", 160, 350, 120, 30));
		colorBox.get(3).setCommand(new ControlCommand() {
			public void Do() {
				colorHandler.setColor(newColor);
				midlet.show(previousCanvas);
			}
		});
	}

	public void setChooser(Displayable previousCanvas, ColorHandler colorHandler) {
		this.previousCanvas = previousCanvas;
		this.colorHandler = colorHandler;
		int c = colorHandler.getColor();
		double[] hsv = RGB2HSV(c);
		originalColor = c;
		newColor = c;
		hueSlider.setHue(hsv[0]);
		saturationSlider.setHue(hsv[0]);
		saturationSlider.setSaturation(hsv[1]);
		valueSlider.setHue(hsv[0]);
		valueSlider.setSaturation(hsv[1]);
		valueSlider.setColorValue(hsv[2]);
		repaint();
	}

	protected void pointerPressed(int x, int y) {
		colorBox.pointerPressed(x, y);
		repaint();
	}

	protected void pointerReleased(int x, int y) {
		colorBox.pointerReleased(x, y);
		repaint();
	}

	protected void pointerDragged(int x, int y) {
		colorBox.pointerPressed(x, y);
		repaint();
	}

	protected void paint(Graphics g) {
		// TODO Auto-generated method stub
		g.setColor(0xff222222);
		g.fillRect(0, 0, 240, 400);
		g.setColor(originalColor);
		g.fillRect(160, 30, 70, 70);
		g.setColor(newColor);
		g.fillRect(160, 100, 70, 70);
		colorBox.paint(g);
	}

	double[] RGB2HSV(int rgb) {

		double r = (double) ((rgb & 0x00ff0000) >>> 16) / 255;
		double g = (double) ((rgb & 0x0000ff00) >> 8) / 255;
		double b = (double) (rgb & 0x000000ff) / 255;
		double h, s, v;

		if (r == g && g == b) {
			h = -1;
			s = 0;
			v = r;
		} else {
			v = Max(r, Max(g, b));
			s = (v - Min(r, Min(g, b))) / v; //
			if (v == r) {
				h = 60 * (g - b) / (s * v);
			} else if (v == g) {
				h = 120 + 60 * (b - r) / (s * v);
			} else {
				h = 240 + 60 * (r - g) / (s * v);
			}
			if (h < 0)
				h += 360;
		}

		double[] hsv = new double[3];
		hsv[0] = h;
		hsv[1] = s;
		hsv[2] = v;
		return hsv;
	}

	private double Max(double a, double b) {
		// TODO Auto-generated method stub
		if (a > b)
			return a;
		return b;
	}

	private double Min(double a, double b) {
		// TODO Auto-generated method stub
		if (a < b)
			return a;
		return b;
	}

	public static int HSV2RGB(double H, double S, double V) {
		double r, g, b;
		double h = H;
		double s = S;
		double v = V;

		if (h == -1) {
			r = g = b = v;
		} else {
			if (h == 360) {
				h = 0;
			}
			int k = (int) (h / 60);
			double max = v;
			double min = v - s * v;
			switch (k) {
			case 0:
				r = max;
				b = min;
				g = min + v * s * h / 60;
				break;
			case 1:
				g = max;
				b = min;
				r = min - v * s * (h / 60 - 2);
				break;
			case 2:
				g = max;
				r = min;
				b = min + v * s * (h / 60 - 2);
				break;
			case 3:
				b = max;
				r = min;
				g = min - v * s * (h / 60 - 4);
				break;
			case 4:
				b = max;
				g = min;
				r = min + v * s * (h / 60 - 4);
				break;
			case 5:
				h -= 360;
				r = max;
				g = min;
				b = min - v * s * h / 60;
				break;
			default:
				r = 0;
				g = 0;
				b = 0;
			}
		}

		// uchar rgb[3];
		int R = (int) (r * 255 + 0.5);
		int G = (int) (g * 255 + 0.5);
		int B = (int) (b * 255 + 0.5);
		// System.out.println(R);
		// System.out.println(G);
		// System.out.println(B);
		int color = 0xff000000 | R << 16 | G << 8 | B;
		return color;
	}

}
